<?php
declare (strict_types = 1);

namespace app\admin\model\admin;

use app\common\model\admin\User as UserModel;
use think\facade\Request;

/**
 * 后台用户模型
 * Class User
 * @package app\admin\model\admin
 */
class User extends UserModel
{
    // 用于生成token的自定义盐
    private $token_salt = '3c80adb2ba83fe02';
    /**
     * 隐藏的字段
     * @var array
     */
    protected $hidden = [
        'password',
    ];

    // 用户登录token
    private string $token = '';

    public function getAvatarAttr($value)
    {
        $info = get_file_url($value);
        return isset($info[0]['url'])?$info[0]['url']:'';
    }
    
    /**
     * 添加新记录
     * @param $data
     * @return bool
     */
    public function add($data): bool
    {
        $data['password'] = encryption_hash($data['password']);
        return $this->save($data);
    }

    /**
     * 编辑记录
     * @param $data
     * @return bool
     */
    public function edit($data): bool
    {
        if(isset($data['password']) && !empty($data['password'])){
            $data['password'] = encryption_hash($data['password']);
        }
        return $this->save($data) !== false;
    }

    /**
     * 后台用户登录
     * @param array $params
     * @return array|bool|null|\think\Model
     */
    public function login(array $params)
    {
        // 验证用户名密码是否正确
        if (!$user = $this->getUserInfoByLogin($params)) {
            $this->error = '登录失败, 用户名或密码错误';
            return false;
        }
        // 记录登录状态, 并记录token
        $userInfo = $user->toArray();
        $data = [
            'admin_user_id' => (int)$userInfo['admin_user_id'],
            'password' => $params['password'],
            'timestamp' => time()+86400*7
        ];
        $this->token = openssl_encrypt(json_encode($data),'AES-128-CBC', md5(Request::domain()), 0, $this->token_salt);
        return $user;
    }

    /**
     * 获取登录的信息
     * @return mixed
     */
    public function getLoginInfo()
    {
        if (($token = $this->getToken()) != '') {
            $token = openssl_decrypt($token,'AES-128-CBC', md5(Request::domain()), 0, $this->token_salt);
            if($token == ''){
                return false;
            }
            $data = json_decode($token, true);
            if($data['timestamp']>0 && $data['timestamp']<time()){
                return false;
            }
            $user = UserModel::detail($data['admin_user_id']);
            // 验证密码是否正确
            if (!password_verify($data['password'], $user['password'])) {
                return false;
            }
            return $user->toArray();
        }
        return false;
    }

    /**
     * 刷新token
     * @return mixed
     */
    public function refreshToken()
    {
        if (($token = $this->getToken()) != '') {
            $token = openssl_decrypt($token,'AES-128-CBC', md5(Request::domain()), 0, $this->token_salt);
            if($token == ''){
                return false;
            }
            $data = json_decode($token, true);
            if($data['timestamp']>0 && ($data['timestamp']+86400*3)<time()){
                return false;
            }
            $user = UserModel::detail($data['admin_user_id']);
            // 验证密码是否正确
            if (!password_verify($data['password'], $user['password'])) {
                return false;
            }
            $res = [
                'admin_user_id' => (int)$data['admin_user_id'],
                'password' => $data['password'],
                'timestamp' => time()+86400*7
            ];
            $this->token = openssl_encrypt(json_encode($res),'AES-128-CBC', md5(Request::domain()), 0, $this->token_salt);
            return $this->token;
        }
        return false;
    }

    /**
     * 返回生成的token
     * @return string
     */
    public function getToken(): string
    {
        if($this->token != ''){
            return $this->token;
        }
        // 获取请求中的token
        $token = Request::header('Authorization', '');
        // 调试模式下可通过param
        if (empty($token) && is_debug()) {
            $token = Request::param('Authorization');
            if (empty($token)) {
                $token = 'Bearer ZEu8EgaOe1AenCOk8S+OyhpJYP33YcgXa2SvUK6/N8qypb++OoFjVpUJH+zmVE383XcnOKm3Qxfea6Qu3AcWL32ACfJBve5LRuA5U3WxnSg=';
            }
        }
        $this->token = substr($token, 7);
        return $this->token;
    }

    /**
     * 获取登录的用户信息
     * @param $data
     * @return array|false|\think\Model
     */
    private function getUserInfoByLogin(array $data)
    {
        // 用户信息
        $useInfo = static::withoutGlobalScope()
            ->where(['user_name' => $data['username'], 'status' => 1])
            ->find();
        if (empty($useInfo)) return false;
        // 验证密码是否正确
        if (!password_verify($data['password'], $useInfo['password'])) {
            return false;
        }
        return $useInfo;
    }

    /**
     * 获取查询条件
     * @param array $param
     * @return array
     */
    private function getFilter(array $param = []): array
    {
        // 默认查询条件
        $params = $this->setQueryDefaultValue($param, [
            'name' => '',   // 用户名/昵称/手机号
            'dept_id' => 0, // 部门ID
            'status' => -1, // 状态
        ]);
        // 检索查询条件
        $filter = [];
        // 用户名/昵称/手机号
        !empty($params['name']) && $filter[] = ['user_name|nick_name|mobile', 'like', "%{$params['name']}%"];
        // 部门ID
        $params['dept_id'] > 0 && $filter[] = ['dept_id', '=', (int)$params['dept_id']];
        // 状态
        $params['status'] > -1 && $filter[] = ['status', '=', (int)$params['status']];
        // 起止时间
        if (!empty($params['betweenTime'])) {
            $times = between_time($params['betweenTime']);
            $filter[] = ['create_time', '>=', $times['start_time']];
            $filter[] = ['create_time', '<', $times['end_time'] + 86400];
        }
        return $filter;
    }
    /**
     * 获取用户列表
     * @param array $param
     * @return \think\Paginator
     * @throws \think\db\exception\DbException
     */
    public function getList(array $param = []): \think\Paginator
    {
        // 检索查询条件
        $filter = $this->getFilter($param);
        // 获取用户列表
        return $this->with(['role', 'dept'])
            ->where($filter)
            ->order(['create_time' => 'desc'])
            ->paginate(input('pageSize',20,'intval'));
    }
}
